package com.king.test;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class MovingRectanglesDemo extends Application {

    private static final double CANVAS_WIDTH = 800;
    private static final double CANVAS_HEIGHT = 600;
    
    private Canvas canvas;
    private GraphicsContext gc;
    private List<Rectangle> rectangles = new ArrayList<>();
    private Rectangle selectedRect = null;
    private double offsetX, offsetY;

	public static void run(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        Pane root = new Pane();
        canvas = new Canvas(CANVAS_WIDTH, CANVAS_HEIGHT);
        gc = canvas.getGraphicsContext2D();
        root.getChildren().add(canvas);
        
        // 创建一些测试矩形
        createTestRectangles();
        
        // 绘制初始状态
        redrawAllRectangles();
        
        // 设置鼠标事件处理
        setupMouseHandlers();
        
        primaryStage.setScene(new Scene(root, CANVAS_WIDTH, CANVAS_HEIGHT));
        primaryStage.setTitle("移动矩形不擦除其他矩形");
        primaryStage.show();
    }

    private void createTestRectangles() {
        rectangles.add(new Rectangle(100, 100, 80, 60, Color.RED));
        rectangles.add(new Rectangle(200, 200, 100, 80, Color.BLUE));
        rectangles.add(new Rectangle(300, 150, 120, 90, Color.GREEN));
        rectangles.add(new Rectangle(150, 300, 90, 70, Color.ORANGE));
    }

    private void setupMouseHandlers() {
        canvas.setOnMousePressed(this::handleMousePressed);
        canvas.setOnMouseDragged(this::handleMouseDragged);
        canvas.setOnMouseReleased(this::handleMouseReleased);
    }

    private void handleMousePressed(MouseEvent event) {
        // 检查是否点击了某个矩形
        for (Rectangle rect : rectangles) {
            if (rect.contains(event.getX(), event.getY())) {
                selectedRect = rect;
                offsetX = event.getX() - rect.getX();
                offsetY = event.getY() - rect.getY();
                break;
            }
        }
    }

    private void handleMouseDragged(MouseEvent event) {
        if (selectedRect != null) {
			// 1. 保存旧位置和计算新位置
			double oldX = selectedRect.getX();
			double oldY = selectedRect.getY();
			double newX = event.getX() - offsetX;
			double newY = event.getY() - offsetY;

			// 2. 计算需要重绘的合并区域（扩大1像素包含边框）
			double minX = Math.min(oldX, newX) - 1;
			double minY = Math.min(oldY, newY) - 1;
			double maxX = Math.max(oldX + selectedRect.getWidth(), newX + selectedRect.getWidth()) + 1;
			double maxY = Math.max(oldY + selectedRect.getHeight(), newY + selectedRect.getHeight()) + 1;

			// 3. 清除整个受影响区域
			gc.clearRect(minX, minY, maxX - minX, maxY - minY);

			// 4. 更新矩形位置（在清除后更新，避免分身）
			selectedRect.setX(newX);
			selectedRect.setY(newY);
            
			// 5. 收集需要重绘的所有矩形（包括被移动矩形覆盖的）
			Set<Rectangle> toRedraw = new HashSet<>();
			for (Rectangle rect : rectangles) {
				if (rect == selectedRect || rectanglesOverlap(rect, minX, minY, maxX - minX, maxY - minY)) {
					toRedraw.add(rect);
				}
			}
            
			// 6. 按正确顺序重绘所有受影响的矩形
			toRedraw.stream().sorted(Comparator.comparingInt(rect -> rect == selectedRect ? 1 : 0))
					.forEach(this::drawRectangle);
		}
	}

	// 判断矩形是否与指定区域重叠
	private boolean rectanglesOverlap(Rectangle rect, double x, double y, double w, double h) {
		return rect.getX() <= x + w && rect.getX() + rect.getWidth() >= x && rect.getY() <= y + h
				&& rect.getY() + rect.getHeight() >= y;
	}


    private void handleMouseReleased(MouseEvent event) {
        selectedRect = null;
    }

    private void redrawAllRectangles() {
        // 先清除整个画布
        gc.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
        
        // 绘制所有矩形
        for (Rectangle rect : rectangles) {
            drawRectangle(rect);
        }
    }

    private void drawRectangle(Rectangle rect) {
		// 先填充矩形内部
        gc.setFill(rect.getColor());
        gc.fillRect(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());

		// 再绘制边框（确保边框在内部颜色之上）
		gc.setStroke(Color.BLACK);
		gc.setLineWidth(1);
		gc.strokeRect(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
    }

    // 矩形类
    private static class Rectangle {
        private double x, y, width, height;
        private Color color;

        public Rectangle(double x, double y, double width, double height, Color color) {
            this.x = x;
            this.y = y;
            this.width = width;
            this.height = height;
            this.color = color;
        }

        public boolean contains(double pointX, double pointY) {
            return pointX >= x && pointX <= x + width && 
                   pointY >= y && pointY <= y + height;
        }

        // Getters and setters
        public double getX() { return x; }
        public void setX(double x) { this.x = x; }
        public double getY() { return y; }
        public void setY(double y) { this.y = y; }
        public double getWidth() { return width; }
        public double getHeight() { return height; }
        public Color getColor() { return color; }
    }
}